package io.kiki.stack.http.feign.form.feign.spring;

import feign.Logger;
import feign.Response;
import feign.codec.Encoder;
import io.kiki.stack.http.feign.form.spring.SpringFormEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

@FeignClient(name = "multipart-support-service", url = "http://localhost:8080", configuration = Client.ClientConfiguration.class)
interface Client {

    @RequestMapping(value = "/multipart/upload1/{folder}", method = POST, consumes = MULTIPART_FORM_DATA_VALUE)
    String upload1(@PathVariable("folder") String folder, @RequestPart("file") MultipartFile file, @RequestParam(name = "message", required = false) String message);

    @RequestMapping(value = "/multipart/upload2/{folder}", method = POST, consumes = MULTIPART_FORM_DATA_VALUE)
    String upload2(@RequestBody MultipartFile file, @PathVariable("folder") String folder, @RequestParam(name = "message", required = false) String message);

    @RequestMapping(value = "/multipart/upload3/{folder}", method = POST, consumes = MULTIPART_FORM_DATA_VALUE)
    String upload3(@RequestBody MultipartFile file, @PathVariable("folder") String folder, @RequestParam(name = "message", required = false) String message);

    @RequestMapping(path = "/multipart/upload4/{id}", method = POST, produces = APPLICATION_JSON_VALUE)
    String upload4(@PathVariable("id") String id, @RequestBody Map<Object, Object> map, @RequestParam("userName") String userName);

    @RequestMapping(path = "/multipart/upload5", method = POST, consumes = MULTIPART_FORM_DATA_VALUE)
    Response upload5(Dto dto);

    @RequestMapping(path = "/multipart/upload6", method = POST, consumes = MULTIPART_FORM_DATA_VALUE)
    String upload6Array(MultipartFile[] files);

    @RequestMapping(path = "/multipart/upload6", method = POST, consumes = MULTIPART_FORM_DATA_VALUE)
    String upload6Collection(List<MultipartFile> files);

    class ClientConfiguration {

        @Autowired
        private ObjectFactory<HttpMessageConverters> messageConverters;

        @Bean
        Encoder feignEncoder() {
            return new SpringFormEncoder(new SpringEncoder(messageConverters));
        }

        @Bean
        Logger.Level feignLogger() {
            return Logger.Level.FULL;
        }
    }
}
